package com.ihr360.oneclick.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.ihr360.excel.ExcelUtil;
import com.ihr360.excel.entity.ImportParams;
import com.ihr360.excel.exception.ExcelCanHandleException;
import com.ihr360.excel.logs.ExcelCommonLog;
import com.ihr360.excel.logs.ExcelLogItem;
import com.ihr360.excel.logs.ExcelLogs;
import com.ihr360.excel.specification.CommonSpecification;
import com.ihr360.oneclick.constant.ConstantString;
import com.ihr360.oneclick.dao.OneClickTermMetaDao;
import com.ihr360.oneclick.dao.OneClickTermMetaTemplateDao;
import com.ihr360.oneclick.dao.SpreadsheetColumnDao;
import com.ihr360.oneclick.dao.SpreadsheetRowHeaderDao;
import com.ihr360.oneclick.dto.OneClickTermMetaDto;
import com.ihr360.oneclick.dto.OneClickTermMetaTemplateDto;
import com.ihr360.oneclick.dto.spreadsheet.SpreadSheetRowHeaderDto;
import com.ihr360.oneclick.dto.spreadsheet.SpreadsheetColumnDto;
import com.ihr360.oneclick.entity.RowHeaderColumn;
import com.ihr360.oneclick.exception.OneClickException;
import com.ihr360.oneclick.service.RowHeaderColumnService;
import com.ihr360.oneclick.util.BeanConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author tom
 * @date 17-12-27
 */
@Service
public class RowHeaderColumnServiceImpl implements RowHeaderColumnService {

    private static final String TEMPLATE_TYPE_EN = "EN";

    @Autowired
    private OneClickTermMetaDao oneClickTermMetaDao;
    @Autowired
    private SpreadsheetRowHeaderDao spreadsheetRowHeaderDao;
    @Autowired
    private SpreadsheetColumnDao spreadsheetColumnDao;
    @Autowired
    private OneClickTermMetaTemplateDao oneClickTermMetaTemplateDao;

    /**
     * 表头上部分无效数据或指定字段未填数据过滤
     *
     * @param file
     * @return
     */
    @Override
    public List<Map> excelFieldFilter(MultipartFile file, String termId) {
        List<List<String>> combinationList = Lists.newArrayList();
        List<Map<String, RowHeaderColumn>> fields = getExcelFieldMapping(termId);
        //邮箱字段不做过滤
        fields.remove(fields.size() - 1);
        for (Map<String, RowHeaderColumn> fieldList : fields) {
            List<String> stringList = Lists.newArrayList();
            for (String key : fieldList.keySet()) {
                stringList.add(key);
            }
            combinationList.add(stringList);
        }
        List<Map> excelData = Lists.newArrayList();
        try {
            ExcelLogs logs = new ExcelLogs();
            ImportParams<Map> importParams = new ImportParams<>();
            importParams.setImportType(Map.class);
            CommonSpecification commonSpecification = CommonSpecification.createCommonSpecification(true);
            //至少有一列有值，否则忽略
            commonSpecification.setAtLeastOneOrIgnoreRow(combinationList);
            //表头判断，包含给定值的第一行认为是表头
            commonSpecification.setHeaderColumnJudge(combinationList);
            importParams.setCommonSpecification(commonSpecification);
            excelData = (ArrayList<Map>) ExcelUtil.importExcel(importParams, file.getInputStream(), logs);
            ExcelCommonLog excelCommonLog = logs.getExcelCommonLog();
            if(excelCommonLog !=null){
                List<ExcelLogItem> excelLogItems = excelCommonLog.getExcelLogItems();
                for(ExcelLogItem excelLog : excelLogItems){
                    if(excelLog.getLogType().name().equals("EXCEL_COMMON_FORMAT_ENCRYPTED") || excelLog.getLogType().equals("EXCEL_COMMON_COMMON")){
                        throw new OneClickException("one_click_term_import_excel_common_format_encrypted","您上传的工资表格式错误，请修改格式后再上传！");
                    }
                    if(excelLog.getLogType().name().equals("EXCEL_COMMON_NO_DATA")){
                        throw new OneClickException("one_click_term_import_excel_common_no_data","您上传的工资表数据为空，请添加数据后再上传！");
                    }
                    if(excelLog.getLogType().name().equals("HEADER_REQUIRED")){
                        throw new OneClickException("one_click_term_import_excel_name_mobile_must","您上传的工资表无员工姓名或手机号，请添加后重新上传！");
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ExcelCanHandleException e) {
            throw new OneClickException("one_click_term_import_excel_head_duplication", "您上传的工资表表头重复，重复列为:" + e.getArgs()[0].toString() + "！");
        }
        return excelData;
    }

    /**
     * 表头映射
     *
     * @param termId
     * @return
     */
    public List<Map<String, RowHeaderColumn>> getExcelFieldMapping(String termId) {
        List<Map<String, RowHeaderColumn>> fields = new ArrayList<>();
        List<RowHeaderColumn> termColumnMetaList = getTermColumnMetaList(termId);
        termColumnMetaList.forEach(rowHeaderColumn -> {
            Map<String, RowHeaderColumn> field = new LinkedHashMap<>();
            String[] columnAliasName = rowHeaderColumn.getColumnAliasName();
            for (int i = 0; i < columnAliasName.length; i++) {
                field.put(columnAliasName[i], rowHeaderColumn);
            }
            fields.add(field);
        });
        return fields;
    }

    @Override
    public List<RowHeaderColumn> getTermFixedColumnMetaList(String termId) {
        List<RowHeaderColumn> columnList = getTermColumnMetaList(termId);
        return columnList.stream().
                filter(RowHeaderColumn::getFixedColumn).collect(Collectors.toList());
    }

    @Override
    public List<RowHeaderColumn> getTermColumnMetaList(String termId) {
        OneClickTermMetaDto oneClickTermMetaDto =
                oneClickTermMetaDao.findByTermIdAndMetaKey(termId, ConstantString.SPREAD_SHEET_COLUMN_META_KEY);
        return JSONArray.parseArray(oneClickTermMetaDto.getMetaValue(), RowHeaderColumn.class);
    }

    @Override
    public Map<String, RowHeaderColumn> getTermFixedColumnMetaMap(String termId) {
        Map<String, RowHeaderColumn> columnMap = new HashMap<>();
        List<RowHeaderColumn> rowHeaderColumnList = getTermFixedColumnMetaList(termId);
        for (RowHeaderColumn rowHeaderColumn : rowHeaderColumnList) {
            columnMap.put(rowHeaderColumn.getColumnFieldMeta(), rowHeaderColumn);
        }
        return columnMap;
    }

    @Override
    public Map<String, RowHeaderColumn> getTermColumnMetaMap(String termId) {
        Map<String, RowHeaderColumn> columnMap = new HashMap<>();
        List<RowHeaderColumn> rowHeaderColumnList = getTermColumnMetaList(termId);
        for (RowHeaderColumn rowHeaderColumn : rowHeaderColumnList) {
            columnMap.put(rowHeaderColumn.getColumnFieldMeta(), rowHeaderColumn);
        }
        return columnMap;
    }

    @Override
    public List<RowHeaderColumn> getSpreadsheetColumnList(String spreadsheetId) {
        return spreadsheetColumnDtoListConvertColumnList(spreadsheetColumnDao.findBySpreadsheetId(spreadsheetId));
    }

    @Override
    public Map<String, RowHeaderColumn> getSpreadsheetColumnMap(String spreadsheetId) {
        return spreadsheetColumnDtoListConvertMap(spreadsheetColumnDao.findBySpreadsheetId(spreadsheetId));
    }

    @Override
    public List<RowHeaderColumn> spreadsheetColumnDtoListConvertColumnList(List<SpreadsheetColumnDto> columnDtoList) {
        List<RowHeaderColumn> rowHeaderColumnList = new ArrayList<>();
        columnDtoList.forEach(spreadsheetColumnDto ->
                rowHeaderColumnList.add(BeanConvertUtils.convertFor(spreadsheetColumnDto, new RowHeaderColumn()))
        );
        return rowHeaderColumnList;
    }

    @Override
    public Map<String, RowHeaderColumn> spreadsheetColumnDtoListConvertMap(List<SpreadsheetColumnDto> columnDtoList) {
        Map<String, RowHeaderColumn> columnMap = new HashMap<>();
        columnDtoList.forEach(spreadsheetColumnDto -> {
            RowHeaderColumn column = new RowHeaderColumn();
            columnMap.put(spreadsheetColumnDto.getColumnFieldMeta(), BeanConvertUtils.convertFor(spreadsheetColumnDto, column));
        });
        return columnMap;
    }

    @Override
    public List<RowHeaderColumn> getSpreadsheetRowHeaderColumnList(String spreadsheetId) {
        SpreadSheetRowHeaderDto spreadSheetRowHeaderDto = spreadsheetRowHeaderDao.findBySpreadsheetId(spreadsheetId);
        //JSONArray.parseArray(spreadSheetRowHeaderDto.getDataStr(), RowHeaderColumn.class)
        return spreadSheetRowHeaderDto.getData();
    }

    /**
     * 查询导出模板示例数据
     */
    @Override
    public List<Object> getTermExampleDataList(String termId, String templateType) {
        OneClickTermMetaDto oneClickTermMetaDto;
        if (TEMPLATE_TYPE_EN.equals(templateType)) {
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, ConstantString.SPREAD_SHEET_EXAMPLE_DATA_EN);
        } else {
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, ConstantString.SPREAD_SHEET_EXAMPLE_DATA);
        }
        return JSONArray.parseArray(oneClickTermMetaDto.getMetaValue());
    }

    /**
     * 查询导出模板表头数据
     */
    @Override
    public List<RowHeaderColumn> getTermTemplateDataList(String termId, String templateType) {
        OneClickTermMetaDto oneClickTermMetaDto;
        if (TEMPLATE_TYPE_EN.equals(templateType)) {
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, ConstantString.SPREAD_SHEET_COLUMN_META_KEY_EN);
        } else {
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, ConstantString.SPREAD_SHEET_COLUMN_META_KEY);
        }
        return JSONArray.parseArray(oneClickTermMetaDto.getMetaValue(), RowHeaderColumn.class);
    }

    /**
     * 查询页面配置显示html
     */
    @Override
    public String getTipTemplate(String termId) {
        OneClickTermMetaDto oneClickTermMetaDto;
        Locale locale = LocaleContextHolder.getLocale();
        String metaKey;
        if (Locale.ENGLISH.equals(locale)) {
            metaKey = ConstantString.ONE_CLICK_TIP_TEMPLATE_EN;
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, metaKey);
        } else {
            metaKey = ConstantString.ONE_CLICK_TIP_TEMPLATE;
            oneClickTermMetaDto = oneClickTermMetaDao.findByTermIdAndMetaKey(termId, metaKey);
        }
        //查询默认配置
        if (oneClickTermMetaDto == null) {
            return oneClickTermMetaTemplateDao.findByMetaKey(metaKey).getMetaValue();
        }
        return oneClickTermMetaDto.getMetaValue();
    }

    /**
     * 查询员工名录导出表头
     */
    @Override
    public List<RowHeaderColumn> getStaffRecordHead() {
        OneClickTermMetaTemplateDto oneClickTermMetaDto;
        Locale locale = LocaleContextHolder.getLocale();
        if (Locale.ENGLISH.equals(locale)) {
            oneClickTermMetaDto = oneClickTermMetaTemplateDao.findByMetaKey(ConstantString.ONE_CLICK_STAFF_RECORD_EN);
        } else {
            oneClickTermMetaDto = oneClickTermMetaTemplateDao.findByMetaKey(ConstantString.ONE_CLICK_STAFF_RECORD);
        }
        return JSONArray.parseArray(oneClickTermMetaDto.getMetaValue(), RowHeaderColumn.class);
    }

}
